package org.changs.s3.common;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.Toast;

import org.changs.s3.common.aidl.DeviceScanCallback;
import org.changs.s3.common.aidl.IDeviceScan;
import org.changs.s3.common.aidl.IUpload;
import org.changs.s3.common.aidl.RemoteService;
import org.changs.s3.common.aidl.UploadCallback;

import timber.log.Timber;

/**
 * Created by yincs on 2017/8/29.
 */

public class RemoteManager implements IDeviceScan, IUpload {

    public static final String DEVICE_REMOTE_PACKAGE = "org.changs.launcher";
    public static final String ACTION_REMOTE_SERVICE = "org.changs.launcher.service.ACTION_REMOTE_SERVICE";
    public static final String ACTION_DEVICE_SCAN = "org.changs.launcher.service.ACTION_DEVICE_SCAN";
    public static final String ACTION_DEVICE_CONNECTED = "org.changs.launcher.service.ACTION_DEVICE_CONNECTED";
    public static final String ACTION_DEVICE_DISCONNECT = "org.changs.launcher.service.ACTION_DEVICE_DISCONNECT";
    public static final String ACTION_SERVICE_CREATE = "org.changs.launcher.service.ACTION_SERVICE_CREATE";
    public static final String ACTION_SERVICE_SCAN = "org.changs.launcher.service.ACTION_SERVICE_SCAN";

    public static final String EXTRA_DEVICE_IP = "extra_device_ip";
    private final Context mContext;
    private RemoteService mRemoteService;

    public RemoteManager(Context context) {
        Timber.d("RemoteManager() called with: context = [" + context + "]");
        mContext = context;
        bindRemoteService();
        registerReceiver();
    }

    private void registerReceiver() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ACTION_SERVICE_CREATE);
        intentFilter.addAction(ACTION_SERVICE_SCAN);
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                log("BroadcastReceiver " + intent.getAction());
                if (mRemoteService == null) {
                    bindRemoteService();
                }
            }
        }, intentFilter);
    }

    private void bindRemoteService() {
        Intent intent = new Intent(ACTION_REMOTE_SERVICE);
        intent.setPackage(DEVICE_REMOTE_PACKAGE);
        boolean bindService = mContext.bindService(intent, new MyDeviceScanConnection(), Context.BIND_AUTO_CREATE);
        log("bindService result is " + bindService);
        Timber.d("bindService result is = " + bindService);
    }


    public String getRemoteIp() {
        return getRemoteIp(false);
    }

    public String getRemoteIp(boolean showCQView) {
        if (!isBindService()) return null;
        try {
            final String remoteIp = mRemoteService.getRemoteIp(showCQView);
            log("remoteIp = " + remoteIp);
            return remoteIp;
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return null;
    }

    public boolean isScanning() {
        if (!isBindService()) return false;
        try {
            return mRemoteService.isScanning();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean startScan() {
        if (!isBindService()) return false;
        try {
            return mRemoteService.startScan();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public void registerCallback(DeviceScanCallback callback) {

    }

    @Override
    public void unregisterCallback(DeviceScanCallback callback) {

    }

    private boolean isBindService() {
        if (mRemoteService == null) {
            err("RemoteService not bind");
            return false;
        }
        return true;
    }

    @Override
    public boolean upload(String msg, String filePath, UploadCallback callback) {
        if (!isBindService()) return false;
        try {
            return mRemoteService.upload(msg, filePath, callback);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }


    private class MyDeviceScanConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            log("onServiceConnected");
            mRemoteService = RemoteService.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            log("onServiceDisconnected");
            mRemoteService = null;
        }
    }


    private void log(String msg) {
        System.out.println("RemoteManager[" + mContext.getPackageName() + "]: " + msg);
    }

    private void err(String msg) {
        System.err.println("RemoteManager[" + mContext.getPackageName() + "]: " + msg);
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }
}
